package com.xtracoder.maven.extenstions;

import com.google.common.base.Joiner;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.Profile;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;

/**
 * This is a template for handling of Maven Lifecycle events.
 */
@Component( role = AbstractMavenLifecycleParticipant.class, hint = "retro" )
public class OnChangeProfileActivatorLifeCycle extends AbstractMavenLifecycleParticipant 
{
    @Requirement
    private Logger logger;
    
    public static MavenSession session;

    public static List<String> goals;
    
    public static Map<File, Map<String, Boolean>> projectProfiles = new HashMap<>();
    public static Map<File, Boolean> projectsToSkip = new HashMap<>();
    
    public OnChangeProfileActivatorLifeCycle() {
    }
    
    @Override
    public void afterSessionStart( MavenSession session ) {
        // logger.info( " ---------------------- afterSessionStart -----------------------------" );
        this.session = session;
        this.goals = session.getGoals();
        logger.info( "Goals: " + Joiner.on(", ").join(goals) );
    }

    @Override
    public void afterProjectsRead( MavenSession session ) {
        // logger.info( " ---------------------- afterProjectsRead -----------------------------" );
        blackListProjectsToSkip(session);
    }
    
    void blackListProjectsToSkip( MavenSession session ) {
        List<MavenProject> projects = session.getProjects();
        
        for( MavenProject project: projects ) {
            if( project.getFile() == null || project.getFile().getParentFile() == null )
                continue;
            
            File projectDir = project.getFile().getParentFile();
            Boolean skip = projectsToSkip.containsKey(projectDir);
            
            if( (skip != null) && skip ) {
                ReactorBuildStatus.globalBlackList(project);
            }
        }
    }
    
    public static void markEnabled(File prjDir, Profile profile, boolean enabled) {
        Map<String, Boolean> profiles = projectProfiles.get(prjDir);
        
        if( profiles == null ) {
            profiles = new HashMap<>();
            projectProfiles.put(prjDir, profiles);
        }
        
        profiles.put(profile.getId(), enabled);
    }
    
    private void dumpProjectPlugins(MavenSession session) {
        List<MavenProject> projects = session.getProjects();
        
        for( MavenProject project: projects ) {
            List<Plugin> plugins = project.getBuild().getPlugins();
            
            for( Plugin plugin: plugins ) {
                List<PluginExecution> executions = plugin.getExecutions();
                
                for( PluginExecution execution: executions ) {
                    logger.info(String.format("%-20s %-20s %-20s %s",
                        project.getArtifactId(), plugin.getArtifactId(), execution.getId(), execution.getPhase()));
                }
            }
        }            
    }
    
    //
    // Code below tries to disable 'active-by-default' profiles - i.e. onChange activator
    // should have higher priority.
    //
    // Unfortunatelly this *** DOES NOT WORK ***, removing profile from the list
    // at this stage affects nothing :(
    //
    private void excludeInactiveProfiles(MavenSession session) {
        List<MavenProject> projects = session.getProjects();
        
        for( MavenProject project: projects ) {
            List<Plugin> plugins = project.getBuild().getPlugins();
            
            for( Plugin plugin: plugins ) {
                List<PluginExecution> executions = plugin.getExecutions();
                
                for( PluginExecution execution: executions ) {
                    logger.info(String.format("%-20s %-20s %-20s %s",
                        project.getArtifactId(), plugin.getArtifactId(), execution.getId(), execution.getPhase()));
                }
            }
            
            if( true )
                continue;
            
            Map<String, Boolean> myActiveProfiles = projectProfiles.get(project.getFile().getParentFile());
            
            if( myActiveProfiles == null )
                continue;
            
            List<Profile> mvnActiveProfiles = project.getActiveProfiles();
            List<Profile> profilesToDisable = null;
            
            for( Profile profile: mvnActiveProfiles ) {
                Boolean enabled = myActiveProfiles.get(profile.getId());
                
                if( (enabled != null) && !enabled ) {
                    if( profilesToDisable == null )
                        profilesToDisable = new LinkedList<>();
                    profilesToDisable.add(profile);
                }
            }
            
            if( profilesToDisable != null ) {
                for( Profile profile: mvnActiveProfiles ) {
                    logger.info( String.format(" disabling profile: %s - %s",
                        project.getArtifactId(), profile.getId()) );
                    mvnActiveProfiles.remove(profile);
                }
            }
        }
    }
}
